package svc

import (
	"fmt"
	"github.com/google/uuid"
	"github.com/zeromicro/go-zero/core/logx"
	"net/http"
	"sync"
	"worker/sse/internal/config"
)

type ServiceContext struct {
	Config config.Config
	SSE    *SseHandler
}

func NewServiceContext(c config.Config) *ServiceContext {
	return &ServiceContext{
		Config: c,
		SSE:    NewSseHandler(),
	}
}

type SseHandler struct {
	uniqueId *UniqueID
	clients  map[uuid.UUID]*Client
	group    sync.Map
}

type Client struct {
	Writer chan string
	Uid    string
}

func NewSseHandler() *SseHandler {
	return &SseHandler{
		uniqueId: NewUniqueId(),
		clients:  make(map[uuid.UUID]*Client),
		group:    sync.Map{},
	}
}

// Serve 处理 SSE 连接
func (h *SseHandler) Serve(w http.ResponseWriter, r *http.Request) {
	// 为每个客户端创建一个 channel
	uuid1 := h.uniqueId.Get()

	clientChan := make(chan string)
	client := &Client{
		Writer: clientChan,
		Uid:    uuid1.String(),
	}
	h.clients[uuid1] = client

	// 客户端断开时清理
	defer func() {
		delete(h.clients, uuid1)
		close(clientChan)
	}()

	go func() {
		clientChan <- fmt.Sprintf("{\"event\":\"connection\",\"clientId\":\"%s\"}", uuid1.String())
	}()

	// 持续监听并推送事件
	for {
		select {
		case msg := <-clientChan:
			// 发送事件数据
			_, err := fmt.Fprintf(w, "data: %s\n\n", msg)
			if err != nil {
				logx.Errorf("Failed to send event: %v\n", err)
				return
			}
			w.(http.Flusher).Flush()
		case <-r.Context().Done():
			// 客户端断开连接
			logx.Infof("Client disconnected: %s", uuid1.String())
			return
		}
	}
}

func (h *SseHandler) SendToAll(msg string) {
	for _, c := range h.clients {
		c.Writer <- msg
	}
}

type UniqueID struct {
	UUID []uuid.UUID
}

func NewUniqueId() *UniqueID {
	return &UniqueID{
		UUID: make([]uuid.UUID, 0),
	}
}

func (u *UniqueID) Get() uuid.UUID {
	if len(u.UUID) == 0 {
		u.fill()
	}
	uId := u.UUID[0]
	u.UUID = u.UUID[1:]
	return uId
}
func (u *UniqueID) fill() {
	for i := 0; i < 10; i++ {
		u.UUID = append(u.UUID, uuid.New())
	}
}
